package main

import (
	"fmt"
	"reflect"
)

// 定义一个结构体
type Person struct {
	name string
	age  int
	addr string
}
type command struct {
	Name    string
	Var     *int
	Comment string
}

func main() {
	// 匿名结构体 没有类型名称 不需要通过type关键字定义就可直接使用
	persons := struct { //匿名结构
		name string
		age  int
	}{name: "匿名", age: 1}
	fmt.Println("person:", persons)

	// 结构体本身是一种类型，像int string 等可以用var的方式声明结构体即可完成实例化
	var p Person
	p.addr = "beijing"
	p.age = 28
	p.name = "zhangdan"
	fmt.Println(p)

	// 键值对实例化结构体
	person := Person{name: "lisi", age: 66}
	person.addr = "shanghai"
	person.name = "lisisi" // 后面的会覆盖前面
	fmt.Println(person)

	// 还可以使用 new 关键字对类型（int string struct）进行实例化
	newperson := new(Person)
	newperson.name = "newpoint"
	newperson.addr = "point"
	newperson.age = 10
	fmt.Printf("newperson %v\n", *newperson)
	fmt.Println(*newperson)

	// 取结构体的地址实例化
	var version int = 1
	cmd := &command{}
	cmd.Comment = "取结构体的地址实例化"
	cmd.Name = "&取地址操作"
	cmd.Var = &version
	fmt.Printf("%v\n", cmd)

	cmd1 := newCommand("func", &version, "&取地址")
	fmt.Println(cmd1)

	pf := reflect.TypeOf(p)
	fmt.Println(pf.Field(0))
}

// 取地址实例化是最广泛的一种结构体实例化方式，使用函数封装
func newCommand(name string, varref *int, comment string) *command {
	return &command{Name: name, Var: varref, Comment: comment}
}
